package org.yxj.requestlib.manager.uploadfile;


import org.yxj.requestlib.i.BaseServer;
import org.yxj.requestlib.i.ProgressListener;
import org.yxj.requestlib.i.UploadFileCallback;
import org.yxj.requestlib.manager.api.ExMultipartBody;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.GsonConverterFactory;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * 上传文件
 *
 */
public class FileUploadRequestManager  {

    /**
     * 实例化okHttp对象
     */
    private static FileUploadRequestManager manager ;

    public static FileUploadRequestManager getInstance(){
        if (null==manager){
            synchronized (FileUploadRequestManager.class){
                if (null==manager){
                    manager = new FileUploadRequestManager();
                }
            }
        }
        return manager ;
    }





    /**
     * 上传文件
     *
     * @param url
     * @param body
     * @param callback
     */
    public void uploadFileByOkHttp(String url,
                                   MultipartBody.Builder body,
                                   final UploadFileCallback<String> callback){

        ExMultipartBody requestBody = new ExMultipartBody(body.build(), new ProgressListener() {
            @Override
            public void onProgress(long contentLength, long mCurrentLength) {
                if (callback!=null){
                    callback.progress(contentLength,mCurrentLength);
                }
            }
        });

        //构建请求
        Request request = new Request.Builder()
                .url(url)//地址
                .post(requestBody)//添加请求体
                .build();

        new OkHttpClient()
                .newCall(request)
                .enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if (callback!=null){
                    callback.failed(-1,e.getMessage());
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (callback!=null){
                    callback.success(new String(response.body().bytes()));
                }
            }
        });
    }



    /**
     * @param uri
     * @param body
     * @param callback
     */
    public  void uploadFileByRetrofit(String uri,
                            MultipartBody.Builder body ,
                            final UploadFileCallback callback){

        OkHttpClient httpClient = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.MINUTES)
                .readTimeout(20, TimeUnit.MINUTES).build();

        Retrofit retrofit = new Retrofit.Builder()
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//                .addConverterFactory(new FileRequestBodyConverterFactory())
//                .addConverterFactory(new RequestManager.NullOnEmptyConverterFactory())
                .addConverterFactory(GsonConverterFactory.create())
                .client(httpClient)
                .baseUrl(uri)
                .build();

        /**
         * 构建要上传的文件
         */
//        RequestBody requestFile = RequestBody.create(MediaType.parse("application/otcet-stream"), file);
//        MultipartBody.Part part = MultipartBody.Part.createFormData("aFile", file.getName(), requestFile);


//        RequestBody builder = new MultipartBody.Builder()
//                .addFormDataPart("","",
//                        RequestBody.create(MediaType.parse("application/otcet-stream"), file))
//                .build() ;

        
        ExMultipartBody exMultipartBody = new ExMultipartBody(body.build(), new ProgressListener() {
            @Override
            public void onProgress(long contentLength, long mCurrentLength) {
                if (callback!=null){
                    callback.progress(contentLength,mCurrentLength);
                }
            }
        });


        BaseServer server = retrofit.create(BaseServer.class);
        server.api(exMultipartBody)
                .subscribeOn(Schedulers.io())
                .subscribeOn(Schedulers.newThread())
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ResponseBody>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        if (callback!=null){
                            callback.failed(-1,e.getMessage());
                        }
                    }

                    @Override
                    public void onNext(ResponseBody obj) {
                        if (callback!=null){
                            try {
                                callback.success(new String(obj.bytes()));
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                });
    }



    static class FileRequestBodyConverterFactory extends Converter.Factory {

        @Override
        public Converter<File, RequestBody> requestBodyConverter(Type type,
                                                                 Annotation[] parameterAnnotations,
                                                                 Annotation[] methodAnnotations,
                                                                 Retrofit retrofit) {
            return new FileRequestBodyConverter();
        }
    }



    static class FileRequestBodyConverter implements Converter<File, RequestBody> {

        @Override
        public RequestBody convert(File file) throws IOException {
            return RequestBody.create(MediaType.parse("application/otcet-stream"), file);
        }
    }
}
